#!/usr/bin/env python3
"""
========================================
RedFire数据同步服务主程序
版本: v5.0.0 (2025-09-16)
功能: MySQL到PostgreSQL数据同步
========================================
"""

import os
import sys
import time
import asyncio
import logging
from datetime import datetime
from typing import Dict, Any, Optional

import pymysql
import psycopg2
import redis
from aiohttp import web, ClientSession
import uvloop

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('/app/logs/sync-service.log'),
        logging.StreamHandler(sys.stdout)
    ]
)
logger = logging.getLogger(__name__)

class DataSyncService:
    """数据同步服务主类"""
    
    def __init__(self):
        self.config = self._load_config()
        self.mysql_conn = None
        self.postgres_conn = None
        self.redis_conn = None
        self.running = False
        
    def _load_config(self) -> Dict[str, Any]:
        """加载配置"""
        return {
            'mysql': {
                'host': os.getenv('MYSQL_HOST', 'mysql-business'),
                'port': int(os.getenv('MYSQL_PORT', 3306)),
                'user': os.getenv('MYSQL_USER', 'redfire_app'),
                'password': os.getenv('MYSQL_PASSWORD', 'redfire_app_2025'),
                'database': os.getenv('MYSQL_DATABASE', 'redfire_trading'),
            },
            'postgres': {
                'host': os.getenv('POSTGRES_HOST', 'postgresql-analytics'),
                'port': int(os.getenv('POSTGRES_PORT', 5432)),
                'user': os.getenv('POSTGRES_USER', 'redfire_analytics'),
                'password': os.getenv('POSTGRES_PASSWORD', 'redfire_pg_2025'),
                'database': os.getenv('POSTGRES_DATABASE', 'redfire_analytics'),
            },
            'redis': {
                'host': os.getenv('REDIS_HOST', 'redis'),
                'port': int(os.getenv('REDIS_PORT', 6379)),
                'password': os.getenv('REDIS_PASSWORD', 'redfire_redis_2025'),
            },
            'sync': {
                'interval': int(os.getenv('SYNC_INTERVAL', 60)),
                'batch_size': int(os.getenv('BATCH_SIZE', 1000)),
                'log_level': os.getenv('LOG_LEVEL', 'INFO'),
            }
        }
    
    async def connect_databases(self):
        """连接数据库"""
        try:
            # 连接MySQL
            self.mysql_conn = pymysql.connect(
                host=self.config['mysql']['host'],
                port=self.config['mysql']['port'],
                user=self.config['mysql']['user'],
                password=self.config['mysql']['password'],
                database=self.config['mysql']['database'],
                charset='utf8mb4',
                autocommit=True
            )
            logger.info("MySQL连接成功")
            
            # 连接PostgreSQL
            self.postgres_conn = psycopg2.connect(
                host=self.config['postgres']['host'],
                port=self.config['postgres']['port'],
                user=self.config['postgres']['user'],
                password=self.config['postgres']['password'],
                database=self.config['postgres']['database']
            )
            logger.info("PostgreSQL连接成功")
            
            # 连接Redis
            self.redis_conn = redis.Redis(
                host=self.config['redis']['host'],
                port=self.config['redis']['port'],
                password=self.config['redis']['password'],
                decode_responses=True
            )
            logger.info("Redis连接成功")
            
        except Exception as e:
            logger.error(f"数据库连接失败: {e}")
            raise
    
    async def health_check(self, request):
        """健康检查接口"""
        try:
            status = {
                'service': 'data-sync-service',
                'version': 'v5.0.0',
                'status': 'healthy' if self.running else 'starting',
                'timestamp': datetime.now().isoformat(),
                'connections': {
                    'mysql': self.mysql_conn is not None,
                    'postgres': self.postgres_conn is not None,
                    'redis': self.redis_conn is not None,
                }
            }
            
            # 测试连接
            if self.mysql_conn:
                with self.mysql_conn.cursor() as cursor:
                    cursor.execute("SELECT 1")
                    status['connections']['mysql'] = True
            
            if self.postgres_conn:
                with self.postgres_conn.cursor() as cursor:
                    cursor.execute("SELECT 1")
                    status['connections']['postgres'] = True
            
            if self.redis_conn:
                self.redis_conn.ping()
                status['connections']['redis'] = True
                
            return web.json_response(status)
            
        except Exception as e:
            logger.error(f"健康检查失败: {e}")
            return web.json_response(
                {'status': 'unhealthy', 'error': str(e)},
                status=500
            )
    
    async def sync_data(self):
        """数据同步主逻辑"""
        logger.info("开始数据同步...")
        
        try:
            # 这里实现具体的数据同步逻辑
            # 示例：同步VnPy tick数据
            with self.mysql_conn.cursor() as mysql_cursor:
                mysql_cursor.execute("""
                    SELECT * FROM dbtickdata 
                    WHERE datetime > DATE_SUB(NOW(), INTERVAL 1 HOUR)
                    LIMIT %s
                """, (self.config['sync']['batch_size'],))
                
                rows = mysql_cursor.fetchall()
                if rows:
                    logger.info(f"同步 {len(rows)} 条tick数据")
                    
                    # 同步到PostgreSQL
                    with self.postgres_conn.cursor() as pg_cursor:
                        # 这里实现具体的插入逻辑
                        pass
                    
                    # 更新Redis缓存
                    self.redis_conn.set('last_sync_time', datetime.now().isoformat())
                    
        except Exception as e:
            logger.error(f"数据同步失败: {e}")
    
    async def sync_worker(self):
        """同步工作线程"""
        self.running = True
        logger.info("数据同步服务启动")
        
        while self.running:
            try:
                await self.sync_data()
                await asyncio.sleep(self.config['sync']['interval'])
            except Exception as e:
                logger.error(f"同步工作线程错误: {e}")
                await asyncio.sleep(10)  # 错误后等待10秒重试
    
    async def start_http_server(self):
        """启动HTTP服务器"""
        app = web.Application()
        app.router.add_get('/health', self.health_check)
        app.router.add_get('/status', self.health_check)
        
        runner = web.AppRunner(app)
        await runner.setup()
        
        site = web.TCPSite(runner, '0.0.0.0', 8080)
        await site.start()
        logger.info("HTTP服务器启动在端口8080")
    
    async def run(self):
        """运行服务"""
        try:
            logger.info("启动RedFire数据同步服务...")
            
            # 连接数据库
            await self.connect_databases()
            
            # 启动HTTP服务器
            await self.start_http_server()
            
            # 启动同步工作线程
            sync_task = asyncio.create_task(self.sync_worker())
            
            # 等待服务运行
            await sync_task
            
        except KeyboardInterrupt:
            logger.info("收到停止信号，正在关闭服务...")
            self.running = False
        except Exception as e:
            logger.error(f"服务运行错误: {e}")
            raise
        finally:
            # 关闭连接
            if self.mysql_conn:
                self.mysql_conn.close()
            if self.postgres_conn:
                self.postgres_conn.close()
            if self.redis_conn:
                self.redis_conn.close()

async def main():
    """主函数"""
    # 使用uvloop提高性能
    if sys.platform != 'win32':
        uvloop.install()
    
    service = DataSyncService()
    await service.run()

if __name__ == '__main__':
    asyncio.run(main())
